module ActiveField

  #
  # == class FieldMapper
  #
  # Maps the model's columns with one of the Fields::*Field class
  #
  class FieldMapper
  
    class << self
      def register_field( field_class )
        # Ex: 'ActiveField::Fields::DateTimeField' becomes 'date_time'
        method_name = ActiveField::Core.underscore field_class.to_s.split('::')[2].gsub(/(\w+)Field/, '\1')
        puts "#{self}.register_field #{method_name}"
        
        define_method method_name.to_sym do | attribute, *options |
          puts "#{self.class}.#{method_name} #{attribute}, options = #{options}"
          
          options = options.last.is_a?(Hash) ? options.last : {}
          @model_class.fields[attribute] = {:class => field_class}.merge options
        end
      end
      
      # Attempt to auto detect the field models according to ActiveRecord's @columns
      # It should work fine for most types, except :binary
      # In which case ActiveField will simply generates a warning a not load the column
      def auto_detect( model_class )
        mapper = FieldMapper.new model_class
        model_class.columns.collect do |column|
          begin
            mapper.send column.type, column.name.to_sym
          rescue NoMethodError
            puts "WARNING : #{self}.auto_detect( #{model_class} ) -> Field '#{column.type}' is not supported."
            nil
          end
        end.compact
      end
    end
    
    def initialize( model_class )
      puts "#{self.class}.initialize #{model_class}"
      @model_class = model_class
    end
  end
  
end
